//app.js
// const mqtt = require('./common/mqtt2.18.8.min.js');
// const mqtt = require('./common/mqtt.min.js');
const netUtils = require('./util/netUtils.js');
const Md5 = require('./util/md5.js');
const mqtt = require('./common/mqtt.js');
const config = require('./config.js')
App({
  onLaunch: function () {
    console.log('app onLaunch');
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力')
    } else {
      wx.cloud.init({
        // env 参数说明：
        //   env 参数决定接下来小程序发起的云开发调用（wx.cloud.xxx）会默认请求到哪个云环境的资源
        //   此处请填入环境 ID, 环境 ID 可打开云控制台查看
        //   如不填则使用默认环境（第一个创建的环境）
        // env: 'my-env-id',
        traceUser: true,
      })
    }
   // this.globalData.bootStatus = true;
    this.autoUpdate()
  },
  onShow () {
    console.log('app onShow');
    this.AppGetDevList();
    //this.reConnect()
    // if (this.globalData.bootStatus==true)
    //     this.AppGetDevList();
  },
  onHide () {
    console.log('app onHide');
     this.logoutConnect()
    //this.globalData.bootStatus = false;
  },
  onUnload(){
    console.log('app onUnload');
    this.logoutConnect()
   // this.globalData.bootStatus=false;
  },
  // mqtt连接
  initSocket: function () {
    var _this = this

    //console.log('cz uuids', _this.globalData.uuids)
    if (this.globalData.MQ && this.globalData.MQ.connected ) {
      // 注册事件
      // _this.globalData.uuids.forEach(uuid => {
      //   _this.registerEvent('wx' +uuid)
      //   // console.log('1注册', 'wx' + uuid);
      // })
      //_this.registerEvent("rev_unlock")
      //_this.registerEvent("$iot/lanbo/msg")
     // _this.registerEvent(config.mqtt_baidu.msg_top)
      console.log('注册 ret');
      return
    }
    config.mqtt.clientId = _this.globalData.phone + _this.randomString(5)
    // console.log('initSocket clientId', config.mqtt.clientId);
    var mqtt_baid_Time = parseInt(new Date().getTime() / 1000)
    
    var mqtt_baid_username =config.mqtt_baidu.adp_type + "@" + config.mqtt_baidu.IoTCoreId + "|" + config.mqtt_baidu.DeviceKey + "|" + mqtt_baid_Time + "|" + config.mqtt_baidu.algorithm_type
   
    var mqtt_baid_password = Md5.hexMD5(config.mqtt_baidu.DeviceKey + "&" + mqtt_baid_Time + "&" + config.mqtt_baidu.algorithm_type + config.mqtt_baidu.device_secret)

    var client = mqtt.connect(config.mqtt_baidu.url, {
      //connectTimeout: 4000, // 超时时间
      protocolVersion: 4, //MQTT连接协议版本
      clean: true, //clean: true, false
      reconnectPeriod: 1000, //1000毫秒，两次重新连接之间的间隔
      connectTimeout: 30 * 1000, //1000毫秒，两次重新连接之间的间隔
      resubscribe: true, //如果连接断开并重新连接，则会再次自动订阅已订阅的主题（默认true）
      clientId: _this.randomString(10),//config.mqtt.clientId,
      // username: config.mqtt.username,
      // password: config.mqtt.password,
      //baidu 
      // username:{adp_type}@{IoTCoreId}|{DeviceKey}|{timestamp}|{algorithm_type}
      // password:{ device_key } & { timestamp } & { algorithm_type }{ device_secret }
      username: mqtt_baid_username,
      password: mqtt_baid_password,
      reconnect: true
    });
    // console.log("mqtt_baid_username:", mqtt_baid_username);
    // console.log("mqtt_baid_password:", mqtt_baid_password);

    this.globalData.MQ = client
    client.on('connect', function () {
      // console.log('连接成功', _this.globalData.uuids);
      // 注册事件
      // _this.globalData.uuids.forEach(uuid => {
      //   _this.registerEvent('wx' +uuid)
      //   console.log('2注册', 'wx' + uuid);
      // })
      _this.registerEvent(config.mqtt_baidu.msg_top)
      console.log('注册 ing');
      //_this.registerEvent("rev_unlock")

    })
    client.on('message', function (uuid, payload) {
      try {
         var str = String.fromCharCode.apply(null,payload)
         var data = JSON.parse(str)
      }
      catch (err) {
        console.log('JSON fail', err)
        return
      }
      // console.log('data type', typeof str,typeof data)
      // console.log('data:', data)
      console.log('data uuid:', data.uuid)
      // console.log('cz uuids', _this.globalData.uuids)
      var uuid_idx = _this.globalData.uuids.indexOf(data.uuid)
      console.log('uuid_idx', uuid_idx)
      if (uuid_idx == -1) {
        console.log('uuid_idx no', uuid_idx)
        return
      }
     // uuid=uuid.replace("wx", "");
      uuid =data.uuid
      _this.globalData.uuid = uuid;
      _this.globalData.duuid = uuid.substring(8);
     // _this.globalData.phone =  
      if (_this.globalData.phone == '')
      {
        var phone = wx.getStorageSync('phone')
        console.log('app phone', phone);
        if ((phone != '') && (typeof phone != 'undefined')) {
          // config.mqtt.clientId = phone + _this.randomString(10)
          _this.globalData.phone = phone;
        }
      }
      

      // console.log('phone', _this.globalData.phone)
      // console.log('uuid', data.uuid, data)
      // console.log('msg_type', data.msg_type)
      // console.log('msg_value', data.msg_value)
      // console.log('msg_user', data.msg_user)
      // console.log('user_id', data.user_id)
      // console.log('value', data.value)
      
      var hTime = + data.timestamp
      var qTime = parseInt(new Date().getTime() / 1000)
      // console.log('后时间', hTime, '前时间', qTime, '时间', qTime - hTime)
      //  alarm_old_uid: '',
      //   alarm_old_timestamp: '',
      if ((data.timestamp != _this.globalData.alarm_old_timestamp) || (uuid != _this.globalData.alarm_old_uid) )
      {
        _this.globalData.alarm_old_uid = uuid;
        _this.globalData.alarm_old_timestamp = data.timestamp;
        if ((qTime - hTime < 60) && (data.msg_type < 100)) {
          console.log('1111')
          wx.request({
            url: config.url.getDevName,
            method: 'POST',
            data: {
              'phone': _this.globalData.phone,
              'uuid': uuid,
              'user_id': data.user_id,
              'client': config.client,
            },
            header: {
              "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
            },
            success(res) {
              console.log('res:', res)
              if (res.data.code == 200) {
                _this.globalData.devicename = res.data.name
                // if (res.data.user_rename != 'undefined')
                _this.globalData.userrename = res.data.user_rename


                {
                  _this.globalData.alarm_show = true // 是否显示弹窗
                  //msg_value1
                  if (data.msg_type == 0) {
                    if ((typeof (_this.globalData.userrename) != 'undefined')) {
                      _this.globalData.alarm_user = config.msg_user[String(data.msg_user)] + ":" + _this.globalData.userrename
                    }
                    else {
                      _this.globalData.alarm_user = config.msg_user[String(data.msg_user)] + ":" + data.user_id
                    }

                    // console.log('1 msg_value length', (data.msg_value > 1))
                    // console.log('1 userrename:', _this.globalData.userrename)

                    if (data.msg_value > 1) {
                      _this.globalData.alarm_info = '门锁' + config.msg_value0[String(data.msg_type)]
                    }
                    else {
                      _this.globalData.alarm_info = config.msg_value1[String(data.msg_value)] + config.msg_value0[String(data.msg_type)]
                    }

                  }
                  else if (data.msg_type == 1) {
                    if ((typeof (_this.globalData.userrename) != 'undefined')) {
                      _this.globalData.alarm_user = config.msg_user[String(data.msg_user)] + ":" + _this.globalData.userrename
                    }
                    else {
                      _this.globalData.alarm_user = config.msg_user[String(data.msg_user)] + ":" + data.user_id
                    }
                    // console.log('2 msg_value length', (data.msg_value > 1))
                    if (data.msg_value > 1) {
                      _this.globalData.alarm_info = '门锁' + config.msg_value0[String(data.msg_type)]
                    }
                    else {
                      _this.globalData.alarm_info = config.msg_value1[String(data.msg_value)] + config.msg_value0[String(data.msg_type)]
                    }

                  }
                  else if (data.msg_type == 2) {
                    _this.globalData.alarm_user = "" //config.msg_user[String(data.msg_user)]

                    if (data.msg_value > config.msg_value2.length) {
                      _this.globalData.alarm_info = '未定义报警类型' + data.msg_value
                    }
                    else
                      _this.globalData.alarm_info = config.msg_value2[Number(data.msg_value)]
                  }
                  else if (data.msg_type == 3) {
                    _this.globalData.alarm_info = "远程开锁请求"
                    _this.globalData.alarm_user = ""
                  }
                  else if (data.msg_type == 4) {
                    _this.globalData.alarm_user = "" //config.msg_user[String(data.msg_user)]
                    if (data.msg_value > config.msg_value3.length) {
                      _this.globalData.alarm_info = '未定义提醒类型' + data.msg_value
                    }
                    else
                    {
                      if ((data.msg_value == 0x09)|| (data.msg_value == 0x0a))
                      {
                        //AA 55 03 04 09 01 05 00 00 15
                        _this.globalData.alarm_info = config.msg_value3[String(data.msg_value)] + " " + config.msg_user[String(data.msg_user)] + ":" + data.user_id
                      }
                      else
                         _this.globalData.alarm_info = config.msg_value3[String(data.msg_value)]
                    }
                     
                  }
                  else if (data.msg_type == 99) {
                    _this.globalData.alarm_info = data.msg_str
                    _this.globalData.timestamp = data.timestamp;
                    _this.globalData.timevalue = data.value;
                    _this.globalData.alarm_user = ""
                    _this.globalData.alarm_time = _this.formatDate(new Date(parseInt(data.timestamp + "000")));
                    //pic_rotate
                  }
                  else {
                    _this.globalData.alarm_info = "报警消息"
                  }
                  // console.log('app:alarm_info', _this.globalData.alarm_info);
                  _this.globalData.timestamp = data.timestamp;
                  _this.globalData.timevalue = data.value;
                  _this.globalData.msg_time= _this.globalData.alarm_time = _this.formatDate(new Date(parseInt(data.timestamp + "000")));
                  //?imageMogr2/rotate/90
                  // if (data.value == 1 || data.value == '1')
                  //   _this.globalData.imgsrc = data.msg_pic && (config.url.CosImgUrl + data.client + '/' + uuid + '/' + data.msg_pic +"?imageMogr2/rotate/90");
                  // else
                  if (data.value==2)
                  {
                    _this.globalData.msg_imgurl =  _this.globalData.imgsrc = data.msg_pic && (config.url.CosImgUrl + data.client + '/' + uuid + '/' + data.msg_pic + config.pic_rotate+"90");
                  }
                  else if (data.value == 3) {
                    _this.globalData.msg_imgurl =  _this.globalData.imgsrc = data.msg_pic && (config.url.CosImgUrl + data.client + '/' + uuid + '/' + data.msg_pic + config.pic_rotate + "270");
                  }
                  else
                    _this.globalData.msg_imgurl = _this.globalData.imgsrc = data.msg_pic && (config.url.CosImgUrl + data.client + '/'+ uuid + '/' + data.msg_pic);

                }
              }

            },
            fail(err) {
              console.err(err)
            }
          })


        }
      }
      _this.globalData.alarm_old_uid = uuid;
      _this.globalData.alarm_old_timestamp = data.timestamp;
    })
    
    client.onConnectionLost = function (responseObject) {

      if (typeof that.data.onConnectionLost === 'function') {
        return that.data.onConnectionLost(responseObject)
      }
      if (responseObject.errorCode !== 0) {
        console.log("onConnectionLost:" + responseObject.errorMessage);
        //检测到与服务器断开连接，设置定时函数一秒后重新连接服务器
        setTimeout(function () {
          this.reConnect()
        }, 1000)
      }
    }
    // 断开事件
    client.on('close', function () {
      console.log("连接断开了！");
      _this.reConnect()
    });
    // 重新连接
    client.on('reconnect', function () {
      console.log("重新连接 re！");
       _this.reConnect()
    });
    // 连接错误
    client.on('error', function (error) {
      console.log("客户端发生错误：error = ", error);
      _this.reConnect()
    });
    // 发送心跳连接
  },
  // 重新连接
  reConnect () {
    let _this = this
    console.log('进入重连', _this.globalData.MQ)
    if (_this.globalData.MQ) {
      _this.globalData.MQ.end()
      _this.globalData.MQ = null
    }

    var phone = wx.getStorageSync('phone')
    console.log('app phone', phone);
    if ((phone != '') && (typeof phone != 'undefined'))
     {
     // config.mqtt.clientId = phone + _this.randomString(10)
      _this.globalData.phone = phone
     }
   // console.log('app clientId', config.mqtt.clientId);
   
    _this.initSocket()
  },
  // 退出连接
  logoutConnect() {
    if (this.globalData.MQ) {
      this.globalData.MQ.end()
      this.globalData.MQ = null;
      this.globalData.MQConnectd = false;
    }
  },

  AppGetDevList: function () {
    var _this = this
    console.log('AppGetDevList')
    var phone = wx.getStorageSync('phone')
    wx.request({
      url: config.url.getDevList,
      method: 'POST',
      data: {
        'phone': phone,
        'client': config.client,
      },
      header: {
        "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
      },
      success(res) {
        //console.log('res:',res)
        if (res.data.code == 200) {
          let result = res.data.data || []
      
          // 订阅消息
          let uuids = result.map(item => {
            return item.fields.uuid
          })
         
          // console.log('设备id=>', res.data.data, uuids)
          _this.globalData.uuids = uuids
          //config.mqtt.clientId = _this.data.phone
          // console.log('index clientId', config.mqtt.clientId)
          _this.initSocket()
        }
        else if (res.data.code == 203) {
          
        }
      },
      // fail(err) {
      //  // console.err(err)
      // }
    })
  },

   Appendzero(obj)
  {
    if(obj<10) return "0" + "" + obj;
    else return obj;
  },

  formatDate(now) {
    var year = now.getFullYear();  //取得4位数的年份
    var month = now.getMonth() + 1;  //取得日期中的月份，其中0表示1月，11表示12月
    var date = now.getDate();      //返回日期月份中的天数（1到31）
    var hour = now.getHours();     //返回日期中的小时数（0到23）
    var minute = now.getMinutes(); //返回日期中的分钟数（0到59）
    var second = now.getSeconds(); //返回日期中的秒数（0到59）
    return year + "-" + this.Appendzero(month) + "-" + this.Appendzero(date) + " " + this.Appendzero(hour) + ":" + this.Appendzero(minute) + ":" + this.Appendzero(second);
  },

  // 订阅事件以及注册回调
  registerEvent (key, callback) {
    let _this = this
    // console.log('注册1', key, this.globalData.MQ)
    // console.log('注册2', this.globalData.MQ.disconnecting)
    if (!this.globalData.MQ || this.globalData.MQ.disconnecting) {
      return
    }
 
    this.globalData.MQ.subscribe(key, {}, function (err) {
      if (!err) {
        //console.log('注册事件成功=>', key)
        console.log('注册事件成功')
        _this.globalData.MQConnectd = true
      }
    })
  },

   randomString(len) {
    len = len || 32;
    var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    var maxPos = $chars.length;
    var pwd = '';
    for(let i = 0; i<len; i++) {
  pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
},

  // 监听全局参数变化，用于弹窗显示
  setWatching: function (key, method) {
    let obj = this.globalData;
    //加个前缀生成隐藏变量，防止死循环发生
    let ori = obj[key];   //obj[key]这个不能放在Object.defineProperty里
    if (ori) {    //处理已经声明的变量，绑定处理
      method(ori);
    }
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: function (value) {
        // console.log('setting ' + key + '  value ');
        this['___' + key] = value;
        method(value);    //数据有变化的时候回调函数，实现同步功能
      },
      get: function () {
        // console.log('getting ' + key + '  value ');
        if (typeof this['__' + key] == 'undefined') {
          if (ori) {
            //这里读取数据的时候隐藏变量和 globalData设置不一样，所以要做同步处理
            this['__' + key] = ori;
            return ori;
          } else {
            return undefined;
          }
        } else {
          return this['__' + key];
        }
      }
    })
  },

  autoUpdate: function () {
    console.log(new Date())
    var self = this
    // 获取小程序更新机制兼容
    if (wx.canIUse('getUpdateManager')) {
      const updateManager = wx.getUpdateManager()
      //1. 检查小程序是否有新版本发布
      updateManager.onCheckForUpdate(function (res) {
        // 请求完新版本信息的回调
        if (res.hasUpdate) {
          //2. 小程序有新版本，则静默下载新版本，做好更新准备
          updateManager.onUpdateReady(function () {
            console.log(new Date())
            wx.showModal({
              title: '更新提示',
              content: '新版本已经准备好，是否重启应用？',
              success: function (res) {
                if (res.confirm) {
                  //3. 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                  updateManager.applyUpdate()
                } else if (res.cancel) {
                  //如果需要强制更新，则给出二次弹窗，如果不需要，则这里的代码都可以删掉了
                  wx.showModal({
                    title: '温馨提示~',
                    content: '请确定更新版本',
                    success: function (res) {
                      self.autoUpdate()
                      return;
                      //第二次提示后，强制更新                      
                      if (res.confirm) {
                        // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                        updateManager.applyUpdate()
                      } else if (res.cancel) {
                        //重新回到版本更新提示
                        self.autoUpdate()
                      }
                    }
                  })
                }
              }
            })
          })
          updateManager.onUpdateFailed(function () {
            // 新的版本下载失败
            wx.showModal({
              title: '已经有新版本了哟~',
              content: '新版本已经上线啦~，请您删除当前小程序，重新搜索打开哟~',
            })
          })
        }
      })
    } else {
      // 如果希望用户在最新版本的客户端上体验您的小程序，可以这样子提示
      wx.showModal({
        title: '提示',
        content: '当前微信版本过低，无法使用该功能，请升级到最新微信版本后重试。'
      })
    }
  },
  // 全局参数
  globalData: {
    bootStatus:false,
    netStatus: true,
    isBiological: false,
    MQ: null, // mq示例
    MQConnectd:false,
    phone:'',//开锁用户
    uuid: '', // 当前触发消息
    duuid: '', // 显示给用户看的ID
    alarm_old_uid:'',
    alarm_old_timestamp: '',
    alarm_show: false, // 是否显示弹窗
    alarm_time: '',
    alarm_info: '',
    imgsrc: '',
    msg_imgurl:'', 
    msg_time: '',
    timestamp: '',
    timevalue: '',
    devicename: '',
    userrename: '',
    uuids: []
  },
})
